package org.apache.lucene.ocean;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.FieldSelector;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.MultiSearcher;

/**
 * MultiSearcher implementation that uses a Snapshot object.
 */
public class OceanSearcher extends MultiSearcher {
  Snapshot snapshot;
  
  public OceanSearcher(Snapshot snapshot) throws IOException {
    super(snapshot.getSearchables());
    this.snapshot = snapshot;
  }
  
  boolean verifyDocsIdsUnique() throws IOException {
    IndexReader reader = snapshot.getIndexReader();
    int maxDoc = reader.maxDoc();
    Set<Long> set = new HashSet<Long>(maxDoc);
    for (int x=0; x < maxDoc; x++) {
      if (reader.isDeleted(x)) continue;
      Document document = reader.document(x);
      Long id = new Long(document.get("id"));
      if (set.contains(id)) {
        return false;
      } else {
        set.add(id);
      }
    }
    return true;
  }
  
  /**
   * Searcher must be closed to decref the snapshot
   */
  public void close() {
    snapshot.decRef();
  }
  
  public Document doc(int n) throws CorruptIndexException, IOException {
    int i = subSearcher(n);       // find searcher index
    Document document = getSearchables()[i].doc(n - getStarts()[i]);   // dispatch to searcher
    //SnapshotSearcher snapshotSearcher = (SnapshotSearcher)searchables[i];
    //IndexID indexId = snapshotSearcher.getIndexSnapshot().getIndex().getId();
    //document.add(new Field(Constants.INDEXID, indexId.toString(), Field.Store.NO, Field.Index.NO));
    return document;
  }

  // inherit javadoc
  public Document doc(int n, FieldSelector fieldSelector) throws CorruptIndexException, IOException {
    int i = subSearcher(n);       // find searcher index
    Document document = getSearchables()[i].doc(n - getStarts()[i], fieldSelector);    // dispatch to searcher
    //SnapshotSearcher snapshotSearcher = (SnapshotSearcher)searchables[i];
    //IndexID indexId = snapshotSearcher.getIndexSnapshot().getIndex().getId();
    //document.add(new Field(Constants.INDEXID, indexId.toString(), Field.Store.NO, Field.Index.NO));
    return document;
  }
  
  public Snapshot getSnapshot() {
    return snapshot;
  }
}
